﻿using Commons;
using RMSIService;
using RMSModel;
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Threading.Tasks;
using RMSModel.Common;
using Microsoft.EntityFrameworkCore;
using RMSModel.Models;
using TencentCloud.Common;
using TencentCloud.Common.Profile;
using TencentCloud.Sms.V20190711;
using TencentCloud.Sms.V20190711.Models;

namespace RMSServiceImpl
{
   public class ShopServiceImpl:IShopService
    {
        private readonly RMSDB db;

        public ShopServiceImpl(RMSDB db)
        {
            this.db = db;
        }

        public ResultType AddGoods(VMGoods g)
        {
            ResultType result = new ResultType();
            var tran = db.Database.BeginTransaction();
            try
            {
                goods gg = new goods() { categoryid=g.categoryid,sort=g.sort,createtime=DateTime.Now,createuser=g.createuser,goodnumber=g.goodnumber,goodsellnumber=g.goodsellnumber,goodsn=g.goodsn,listpicurl=g.listpicurl,masterpicurl=g.masterpicurl,name=g.name,price=g.price,status=g.status};
                var d= db.goods.Add(g).Entity;
                db.SaveChanges();
                gooddetailshtml gd = new gooddetailshtml() { goodsid = d.id, goodhtml = g.goodhtml };
                db.gooddetailshtml.Add(gd);
                db.SaveChanges();
                List<goodsimagelist> gima = new List<goodsimagelist>();
                foreach(var str in g.imageList)
                {
                    goodsimagelist go = new goodsimagelist() {goodsid=d.id,imagelisturl=str };
                    gima.Add(go);
                }
                db.goodsimagelist.AddRange(gima);
                db.SaveChanges();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType AddGoodsType(goodstype g)
        {
            ResultType result = new ResultType();
            try
            {
                db.goodstype.Add(g);
                db.SaveChanges();
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType DeleteGoods(List<goods> g)
        {
            ResultType result = new ResultType();
            try
            {
                db.goods.RemoveRange(g);
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType DeleteGoodsType(goodstype g)
        {
            ResultType result = new ResultType();
            try
            {
                db.goodstype.Remove(g);
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        /// <summary>
        /// 获取所有商品
        /// </summary>
        /// <returns></returns>
        public ResultType<List<VMGoods>> GetAllGoods()
        {
            ResultType<List<VMGoods>> result = new ResultType<List<VMGoods>>();
            try
            {
                var data = from m1 in db.goods
                           join m2 in db.goodstype on m1.categoryid equals m2.id into m2_join
                           from m2 in m2_join.DefaultIfEmpty()
                           select new VMGoods
                           {
                               id = m1.id,
                               goodnumber=m1.goodnumber,
                               goodsellnumber=m1.goodsellnumber,
                               goodsn=m1.goodsn,
                               goodstypename=m2.name,
                               name=m1.name,
                               price=m1.price,
                               status = m1.status,
                               createtime = m1.createtime,
                               createuser = m1.createuser,
                               updatetime = m1.updatetime,
                               updateuser = m1.updateuser,
                               sort=m1.sort

                           };
                result.Data = data.ToList();
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }
        /// <summary>
        /// 获取所有商品类型
        /// </summary>
        /// <returns></returns>
        public ResultType<List<goodstype>> GetAllGoodsType()
        {

            ResultType<List<goodstype>> result = new ResultType<List<goodstype>>();
            try
            {
                result.Data = db.goodstype.ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public List<TreeModel> GetAllGoodsTypeTree()
        {
            List<goodstype> data = GetAllGoodsType().Data;
            List<TreeModel> treeModels = new List<TreeModel>();
            foreach (goodstype m in data)
            {
                TreeModel menu = new TreeModel() { id = m.id.ToString(), parentid = m.parentid.ToString(), code = m.id.ToString(), name = m.name };
                treeModels.Add(menu);
            }
            Dictionary<string, TreeModel> dict = treeModels.ToDictionary(loc => loc.id);

            foreach (TreeModel loc in dict.Values)
            {
                if ("0".Equals(loc.parentid))
                {
                    continue;
                }

                if (loc.parentid != loc.id)
                {
                    dict[loc.parentid].children.Add(loc);
                }
            }
            foreach (TreeModel loc in dict.Values)
            {
                if (!"0".Equals(loc.parentid))
                {
                    dict.Remove(loc.id);
                }
            }

            return dict.Values.ToList();
        }

        public ResultType<List<goodstype>> GetAllGoodsTypeWhereLV1()
        {

            ResultType<List<goodstype>> result = new ResultType<List<goodstype>>();
            try
            {
                result.Data = db.goodstype.Where(p=>p.level== "LV1").ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<List<order>> GetAllOrder()
        {
            ResultType<List<order>> result = new ResultType<List<order>>();
            try
            {
                var data= db.orders.ToList();
                //var d = data.GroupBy(p => p.orderstatus);
                //result
                result.Data = data;
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<VMGoods> GetGoodsById(int id)
        {
            ResultType<VMGoods> result = new ResultType<VMGoods>();
            try
            {
                goods g = db.goods.Find(id);
                VMGoods vng = new VMGoods() {categoryid=g.categoryid,createtime=g.createtime,createuser=g.createuser,goodnumber=g.goodnumber,goodsellnumber=g.goodsellnumber,goodsn=g.goodsn,id=g.id,listpicurl=g.listpicurl,masterpicurl=g.masterpicurl,name=g.name,price=g.price,sort=g.sort,status=g.status,updatetime=g.updatetime,updateuser=g.updateuser };
                var imageList = db.goodsimagelist.FromSqlRaw(string.Format("select * from goodsimagelist where goodsid={0}", id));
                if (imageList.Count() > 0)
                {
                    vng.imageList = imageList.Select(p => p.imagelisturl).ToList();
                }
                var goodhtml = db.gooddetailshtml.FromSqlRaw(string.Format("select * from gooddetailshtml where goodsid={0}", id));
                if (goodhtml.Count() > 0)
                {
                    vng.goodhtml = goodhtml.Select(p => p.goodhtml).First();
                }

                result.Data = vng;
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }

        public ResultType<goodstype> GetGoodsTypeById(int id)
        {
            ResultType<goodstype> result = new ResultType<goodstype>();
            try
            {
                result.Data = db.goodstype.Find(id);
            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<List<order>> GetOrderBySn(string no)
        {
            ResultType<List<order>> result = new ResultType<List<order>>();
            try
            {
                result.Data = db.orders.Where(p=>p.ordersn== no).ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<List<order>> GetOrderByStatus(int status)
        {
            ResultType<List<order>> result = new ResultType<List<order>>();
            try
            {
                
                if (status == -1)
                {
                    var data = db.orders.ToList();
                    result.Data = data;
                }
                else
                {
                    var data = db.orders.Where(p => p.orderstatus == status).ToList();
                    result.Data = data;
                }
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType<Dictionary<string, int>> GetOrderGroupCount()
        {
            ResultType<Dictionary<string, int>> result = new ResultType<Dictionary<string, int>>();
            try
            {
                var data = db.orders.ToList().GroupBy(p=>p.orderstatus);
                foreach (var item in data)
                {
                    result.Data.Add(item.Key.ToString(),item.Count());
                }
                
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType UpdateGoods(VMGoods g)
        {
            ResultType result = new ResultType();
            var tran = db.Database.BeginTransaction();
            try
            {
                goods gg = new goods() {id=g.id,updatetime=g.updatetime,updateuser=g.updateuser, categoryid = g.categoryid, sort = g.sort, createtime = DateTime.Now, createuser = g.createuser, goodnumber = g.goodnumber, goodsellnumber = g.goodsellnumber, goodsn = g.goodsn, listpicurl = g.listpicurl, masterpicurl = g.masterpicurl, name = g.name, price = g.price, status = g.status };
                db.goods.Update(gg);
                db.Entry(gg).Property(p => p.createtime).IsModified = false;
                db.Entry(gg).Property(p => p.createuser).IsModified = false;
                db.SaveChanges();

                //db.gooddetailshtml.FromSqlRaw(string.Format("delete gooddetailshtml where goodsid={0}", g.id));
                db.gooddetailshtml.RemoveRange(db.gooddetailshtml.FromSqlRaw(string.Format("select * from gooddetailshtml where goodsid={0}", g.id)));
                gooddetailshtml dhtl = new gooddetailshtml() {goodsid=g.id, goodhtml=g.goodhtml};
                db.gooddetailshtml.Add(dhtl);
                db.SaveChanges();


                db.goodsimagelist.RemoveRange(db.goodsimagelist.FromSqlRaw(string.Format("select * from goodsimagelist where goodsid={0}", g.id)));
                List<goodsimagelist> list = new List<goodsimagelist>();
                foreach(var str in g.imageList)
                {
                    goodsimagelist gima = new goodsimagelist() { goodsid = g.id, imagelisturl =str};
                    list.Add(gima);
                }
                db.goodsimagelist.AddRange(list);
                db.SaveChanges();
                tran.Commit();
            }
            catch (Exception ex)
            {
                tran.Rollback();
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType UpdateGoodsStatus(int id, bool status)
        {
            ResultType result = new ResultType();
            try
            {
                goods g = db.goods.Find(id);
                g.status = status;
                db.SaveChanges();

            }catch(Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType UpdateGoodsType(goodstype g)
        {
            ResultType result = new ResultType();
            try
            {
                db.goodstype.Update(g);
                db.Entry(g).Property(p => p.createtime).IsModified = false;
                db.Entry(g).Property(p => p.createuser).IsModified = false;
                db.SaveChanges();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }
        public ResultType<List<shopuser>> GetAllShopUser()
        {
            ResultType<List<shopuser>> result = new ResultType<List<shopuser>>();
            try
            {
                result.Data = db.shopuser.ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }
            return result;
        }

        public ResultType ConsignmentAsync(order o)
        {
            ResultType result = new ResultType();
            try
            {
                order or = db.orders.Find(o.id);
                if (or.orderstatus == 2)
                {
                    result.ResultCode = 1;
                    result.ResultMsg = "订单已发货";
                    return result;
                }
                or.expressname = o.expressname;
                or.expresssn = o.expresssn;
                or.orderstatus = 2;
                db.orders.Attach(or);
                db.Entry(or).State = EntityState.Modified;
                db.SaveChanges();
                SendMsgAsync($"{or.expressname}  {or.expresssn}", or.mobile);
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }

        public static async Task SendMsgAsync(string str,string phonenumber)
        {


            try
            {
                /* 必要步骤：
                 * 实例化一个认证对象，入参需要传入腾讯云账户密钥对 secretId 和 secretKey
                 * 本示例采用从环境变量读取的方式，需要预先在环境变量中设置这两个值
                 * 您也可以直接在代码中写入密钥对，但需谨防泄露，不要将代码复制、上传或者分享给他人
                 * CAM 密匙查询：https://console.cloud.tencent.com/cam/capi
                 */
                Credential cred = new Credential
                {
                    SecretId = "AKIDA7pK0RfYHq9dw1bKYgeNrztWv9VkGdDY",
                    SecretKey = "OYtzwe8NTQ9dDcnjKgsqZ4OUYO1SgeXB"
                };


                /* 非必要步骤:
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                ClientProfile clientProfile = new ClientProfile();
                /* SDK 默认用 TC3-HMAC-SHA256 进行签名
                 * 非必要请不要修改该字段 */
                clientProfile.SignMethod = ClientProfile.SIGN_TC3SHA256;
                /* 非必要步骤
                 * 实例化一个客户端配置对象，可以指定超时时间等配置 */
                HttpProfile httpProfile = new HttpProfile();
                httpProfile.Timeout = 10;
                clientProfile.HttpProfile = httpProfile;
                SmsClient client = new SmsClient(cred, "", clientProfile);
                SendSmsRequest req = new SendSmsRequest();
                req.SmsSdkAppid = "1400252718";
                req.Sign = "蛋蛋家的果园";
                req.PhoneNumberSet = new String[] { "+86"+phonenumber };
                req.TemplateID = "442337";
                req.TemplateParamSet = new String[] { str, "" };
                await client.SendSms(req);
            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }
            Console.Read();
        }

        public ResultType<List<nideshop_shipping>> GetAllShipping()
        {
            ResultType<List<nideshop_shipping>> result=new ResultType<List<nideshop_shipping>>();
            try
            {
                result.Data = db.nideshop_shipping.ToList();
            }
            catch (Exception ex)
            {
                result.ResultCode = 1;
                result.ResultMsg = ex.Message;
            }

            return result;
        }
    }
}
